/*
 * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
 * Description:Initial Draft
 * Author: Hisilicon multimedia software group
 * Create: 2019/01/15
 */

#ifndef HI_SYSLINK_H
#define HI_SYSLINK_H

#include "hi_type.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/* app message base id : [28bit~31bit] unique */
#define HI_SYSLINK_MSG_BASEID 0x20000000

/*
 * application message id define rule | base(4bit) | component(8bit) | module(8bit) | msg(12bit) |
 * component : unique in system
 * module    : unique in component
 * msg       : unique in module
 */
#define hi_syslink_msg_id_define(component, module, msg) \
    ((HI_SYSLINK_MSG_BASEID) | ((component) << 20) | ((module) << 12) | (msg))

#define hi_syslink_mod_id_define(component, module) \
    ((HI_SYSLINK_MSG_BASEID) | ((component) << 20) | ((module) << 12))

#define HI_SYSLINK_BOOT_INFO_LEN 32

/* error code */
#define HI_SYSLINK_BASE_ERRNO           0x68690000
#define HI_SYSLINK_ERR_NULL_PTR         (HI_SYSLINK_BASE_ERRNO + 0x0000)
#define HI_SYSLINK_ERR_ILLEGAL_PARAM    (HI_SYSLINK_BASE_ERRNO + 0x0001)
#define HI_SYSLINK_ERR_INIT_FAIL        (HI_SYSLINK_BASE_ERRNO + 0x0002)
#define HI_SYSLINK_ERR_EXIT_FAIL        (HI_SYSLINK_BASE_ERRNO + 0x0003)
#define HI_SYSLINK_ERR_EXIST            (HI_SYSLINK_BASE_ERRNO + 0x0004)
#define HI_SYSLINK_ERR_UNEXIST          (HI_SYSLINK_BASE_ERRNO + 0x0005)
#define HI_SYSLINK_ERR_BOOT_INFO        (HI_SYSLINK_BASE_ERRNO + 0x0006)
#define HI_SYSLINK_ERR_NO_MEM           (HI_SYSLINK_BASE_ERRNO + 0x0007)
#define HI_SYSLINK_ERR_TIMEOUT          (HI_SYSLINK_BASE_ERRNO + 0x0008)
#define HI_SYSLINK_ERR_INNER            (HI_SYSLINK_BASE_ERRNO + 0x0009)
#define HI_SYSLINK_ERR_MOD_UNEXIST      (HI_SYSLINK_BASE_ERRNO + 0x000a)
#define HI_SYSLINK_ERR_TASK_CREATE_FAIL (HI_SYSLINK_BASE_ERRNO + 0x000b)
#define HI_SYSLINK_ERR_UNCONNECTED      (HI_SYSLINK_BASE_ERRNO + 0x000c)
#define HI_SYSLINK_ERR_SEND_FAIL        (HI_SYSLINK_BASE_ERRNO + 0x000d)
#define HI_SYSLINK_ERR_MSG_BUSY         (HI_SYSLINK_BASE_ERRNO + 0x000e)

typedef struct {
    hi_u8 group_number;    /* gpio group number, Range:[0,GPIO_GROUP_NUM) */
    hi_u8 bit_number;      /* gpio bit number, Range:[0,GPIO_BIT_NUM) */
} hi_syslink_gpio_info;

typedef struct {
    hi_syslink_gpio_info sdio_clk_out;  /* SDIOx_CCLK_OUT gpio info */
    hi_syslink_gpio_info sdio_cmd;      /* SDIOx_CCMD gpio info */
    hi_syslink_gpio_info sdio_int;      /* SDIO interrupt gpio info */
} hi_syslink_sdio_pin;

typedef struct {
    hi_u8 sdio_dev;                     /* SDIO dev, Range:[0,MAX_MMC_NUM) */
    hi_syslink_sdio_pin sdio_pin;       /* SDIO pin info */
} hi_syslink_sdio_cfg;

typedef enum {
    HI_SYSLINK_BOOT_INFO,
    HI_SYSLINK_PIN_MUX_GPIO,
    HI_SYSLINK_PIN_MUX_SDIO,
    HI_SYSLINK_NET_CHANGED,
    HI_SYSLINK_NET_CONFLICT,
    HI_SYSLINK_ESTABLISHED,
    HI_SYSLINK_INTER_EXCEPTION,
} hi_syslink_callback_type;

typedef struct {
    hi_u8 len;
    hi_u8 info[HI_SYSLINK_BOOT_INFO_LEN];
} hi_syslink_boot_info;

typedef enum {
    HI_SYSLINK_NET_IPV4_READY,
    HI_SYSLINK_NET_IPV4_NOT_READY,
    HI_SYSLINK_NET_IPV6_READY,
    HI_SYSLINK_NET_IPV6_NOT_READY,
} hi_syslink_net_changed;

typedef enum {
    HI_SYSLINK_EXCEPTION_FATAL,
    HI_SYSLINK_EXCEPTION_CONN_FAIL,
    HI_SYSLINK_EXCEPTION_BEATHEART,
} hi_syslink_inner_exception;

typedef union {
    /* args to HI_SYSLINK_BOOT_INFO callback */
    hi_syslink_boot_info boot_info;
    /* args to HI_SYSLINK_NET_CHANGED callback */
    hi_syslink_net_changed net_changed;
    /* args to HI_SYSLINK_INTER_EXCEPTION callback */
    hi_syslink_inner_exception exception;
} hi_syslink_callback_args;

typedef hi_void (*hi_syslink_callback)(hi_syslink_callback_type type, hi_syslink_callback_args *args);

typedef struct {
    hi_syslink_sdio_cfg sdio_cfg;
    hi_syslink_callback callback;
} hi_syslink_init_attr;

typedef struct {
    hi_u8 *request;
    hi_u32 req_len;
} hi_syslink_request;

typedef struct {
    hi_u8 *response;
    hi_u32 resp_len;
} hi_syslink_response;

typedef hi_s32 (*hi_syslink_msg_cb)(hi_u32 msg_id, const hi_syslink_request *request, hi_syslink_response *response);

typedef enum {
    HI_SYSLINK_TTY_SHELL = 0,
    HI_SYSLINK_TTY_AT,
    HI_SYSLINK_TTY_DIAG,
    HI_SYSLINK_TTY_SIGMA,
    HI_SYSLINK_TTY_BUTT
} hi_syslink_tty_type;

typedef enum {
    HI_SYSLINK_LEVEL_CLOSE,
    HI_SYSLINK_LEVEL_ERROR,
    HI_SYSLINK_LEVEL_WARN,
    HI_SYSLINK_LEVEL_INFO,
    HI_SYSLINK_LEVEL_DEBUG,
} hi_syslink_log_level;

hi_s32 hi_syslink_init(const hi_syslink_init_attr *init_attr);

hi_s32 hi_syslink_deinit(hi_void);

hi_s32 hi_syslink_register_msg_cb(hi_u32 mod_id, hi_syslink_msg_cb msg_cb);

hi_s32 hi_syslink_unregister_msg_cb(hi_u32 mod_id, hi_syslink_msg_cb msg_cb);

hi_s32 hi_syslink_send_msg_async(hi_u32 msg_id, const hi_syslink_request *request);

hi_s32 hi_syslink_send_msg_sync(hi_u32 msg_id, const hi_syslink_request *request,
    hi_syslink_response *response, hi_u32 timeout_ms);

hi_s32 hi_syslink_get_boot_info(hi_syslink_boot_info *boot_info);

hi_s32 hi_syslink_enable_tty(hi_syslink_tty_type type, hi_bool enable);

hi_s32 hi_syslink_attach_tty(hi_syslink_tty_type type);

hi_s32 hi_syslink_set_log_level(hi_syslink_log_level log_level);

hi_s32 hi_syslink_get_log_level(hi_syslink_log_level *log_level);

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */

#endif /* HI_SYSLINK_H */
